layui.define(['treeTable', 'form', 'jquery', 'helper', 'func', 'layer', 'ax'], function (exports) {

    var table = layui.treeTable,
        form = layui.form,
        layer = layui.layer,
        $ = layui.jquery,
        helper = layui.helper,
        func = layui.func,
        GridView = {},
        $ax = layui.ax,
        // 构造器
        Class = function (options, events) {
            this.config = $.extend(this.config, options || {})
            this.events = $.extend(this.events, events || {})
        },
        theTable = function () {

            // 渲染表格组件
            this.renderTable(this.config.table);

            // 渲染行内编辑
            this.renderEditor(this.config.editor);

            // 渲染tools
            this.renderTool();

            // 渲染toolbar
            this.renderToolbar();

            return this.config.inst;
        }

    // 默认配置
    Class.prototype.config = {
        searchFilter: 'search',
        tableId: '',
        tableFilter: '',
        inst: null,
        defaultTable: {
            limit: 15,
            limits: [10, 20, 50, 100],
            cols: [[]],
            method: "get",
            request: {"pageName": "page", "limitName": "pagesize"},
            contentType: "application/json",
            url: "",
            toolbar: "#toolBar",
            page: {"hash": "fenye"},
            defaultToolbar: ["filter", "print"]
        },
        table: {}, // table 配置
        editor: {}, // 行内编辑
        eventOptions: {}
    };

    /**
     * 生成table组件
     * @param options
     */
    Class.prototype.renderTable = function (options) {
        options.id = this.config.tableId;
        options.elem = '#' + this.config.tableId;

        var that = this, config = new helper.getTableConfig();

        helper.hasKeyFnt(options, 'headers', function (O, K) {
            config.setProperty('headers', O[K])
        });

        helper.hasKeyFnt(options, 'url', function (O, K) {
            config.setHeader('Search-Class', that.config.searchClass)
        });

        if (that.config.searchFilter != null) {
            config.setConditions(
                $.extend(options['defaultCondition'],
                    form.val(that.config.searchFilter),
                    options['fixedCondition']));

            // 渲染搜索组件
            form.on('submit(' + that.config.searchFilter + '-btn)', function (data) {
                that.reloadTable(null, 1);
                return false;
            })
        }

        if (helper.hasKey(options, 'page')) {
            helper.hasKeyFnt(options['page'], 'hash', function (page, hash) {
                config.setPage('curr', location.hash.replace('#!' + page[hash] + '=', ''));
                config.setPage('hash', page[hash]);
            });
        }

        var doneFnt;
        if (helper.hasKey(options, 'done')) {
            doneFnt = options.done
        }

        config.setProperty('done', function (res, curr, count) {
            doneFnt && doneFnt(res, curr, count)
            // 开启count缓存
            if (that.config.countCache) {
                config.setHeader('Cancel-Count', -1);
                this.headers['Cancel-Count'] = count || -1
            }
        })

        // 渲染table 组件
        this.config.inst = table.render($.extend(this.config.defaultTable, options, config));
    };

    /**
     * 刷新table组件
     * @param order
     * @param resetPage
     * @param resetCount
     */
    Class.prototype.reloadTable = function (order, resetPage, resetCount) {

        var config = new helper.getTableConfig(),
            tableIns = this.config.inst,
            options = this.config;

        helper.hasKeyFnt(options, 'headers', function (O, K) {
            config.setProperty('headers', O[K])
        });

        helper.hasKeyFnt(options.table, 'url', function (O, K) {
            if (order === null) config.setHeader('Search-Class', options.searchClass)
        });

        if (options.searchFilter != null) {
            config.setConditions($.extend(options.table['defaultConditions'], form.val(options.searchFilter)));
        }

        if (order instanceof Object) {
            tableIns.config.where.sort = {}
            // config.setProperty('initSort', order);
            if (order.type !== null) {
                config.setSortValue(order.field, order.type);
            }
        }

        if (helper.hasKey(options, 'page')) {
            helper.hasKeyFnt(options['page'], 'hash', function (page, hash) {
                if (resetPage instanceof Number) config.setPage('curr', resetPage);
            });
        }

        if (resetCount === true) {
            config.setHeader('Cancel-Count', -1);
        }
        config = $.extend(this.config.defaultTable, config);
        this.config.inst.reload(config);
    };

    /**
     * 渲染toolbar
     */
    Class.prototype.renderToolbar = function () {
        var that = this;
        table.on('toolbar(' + that.config.tableId + ')', function (obj) {
            var config = helper.getValue(that.config.eventOptions, obj.event, {});
            that.events[obj.event] && that.events[obj.event].call(this, obj, config, that)
        })
    };

    /**
     * 渲染tool
     */
    Class.prototype.renderTool = function () {
        var that = this;
        table.on('tool(' + this.config.tableId + ')', function (obj) {
            var config = helper.getValue(that.config.eventOptions, obj.event, {});
            that.events[obj.event] && that.events[obj.event].call(this, obj, config, that)
        })
    };

    /**
     * 渲染行内编辑
     */
    Class.prototype.renderEditor = function (options) {
        var that = this;
        table.on('edit(' + this.config.tableId + ')', function (obj) {

            // 自定义
            var func = helper.getValue(options, 'func', null)
            if (typeof func === "function") {
                func(obj, that)
                return;
            }

            if (helper.emptyKey(options, 'url')) {
                Kong.error('请先配置URL！');
                return false
            }

            var message = helper.getValue(options, 'message', '确定修改？');

            layer.alert(message, function (index) {
                // obj 更新的数据、options is edit's configuration

                var id = obj.data.id
                var ajax = new $ax(options.url, function (data) {
                    Kong.success("修改成功！")
                })
                ajax.setDataDataValue(obj.field, obj.value);
                ajax.setDataConditionValue("id", id)
                ajax.sendJson()
                layer.close(index)


            })
        });

    };

    Class.prototype.events = {

        /**
         *
         * @param obj  event=create；config=当前table实例对象
         * @param config 配置项
         * @param that  当前Class实例对象
         * @returns {boolean}
         */
        create: function (obj, config, that) {

            if (!helper.hasKey(config, 'url')) {
                Kong.error('请先配置create请求地址')
                return false
            }

            var condition = helper.getValue(config, 'condition', '')
                , params = helper.getCondition(condition, obj)
                , label = helper.getValue(config, 'label', '新建')
                , height = helper.getValue(config, 'height', 800);

            func.open({
                height: height,
                title: label,
                content: config.url + '?s=create&' + helper.urlEncode(params),
                tableId: that.config.tableId,
                endCallback: function () {
                    that.reloadTable(null, null)
                }
            });
        },

        // 批量删除
        deleteBatch: function (obj, config, that) {
            var checkStatus = that.config.inst.checkStatus()
            if (checkStatus.length <= 0) {
                Kong.error('请先选择要操作的数据!');
                return false;
            }

            // 自定义处理函数
            if (helper.hasKey(config, 'func')) {
                func(obj, config, that)
                return;
            }

            if (!helper.hasKey(config, 'url')) {
                Kong.error('请先配置Batch Delete请求地址');
                return false;
            }

            // condition用于处理data获取主键key
            var condition = helper.getValue(config, 'condition', 'id'),
                ids = helper.getPrimaries(condition, checkStatus),
                message = helper.getValue(config, 'message', '确定删除该项目？'),
                afterFunc = helper.getValue(config, 'after', null);

            layer.alert(message, function (index) {
                // 提交配置文件、主键集合、layer的index
                var ajax = new $ax(config.url, function (data) {
                    Kong.success("删除成功！")
                    that.reloadTable(null, null)
                    afterFunc && afterFunc(obj, ids, that)
                })
                ajax.setMethod("post")
                ajax.setDataValue("ids", ids)
                ajax.sendJson()
                layer.close(index)
            });
        },

        // 更新
        update: function (obj, config, that) {
            if (!helper.hasKey(config, 'url')) {
                layer.alert('请先配置update请求地址');
                return false
            }

            /**
             * condition string | function
             */
            var condition = helper.getValue(config, 'condition', 'id')
                , params = helper.getCondition(condition, obj.data)
                , label = helper.getValue(config, 'label', '更新')
                , height = helper.getValue(config, 'height', 800);

            func.open({
                height: height,
                title: label,
                content: config.url + '?s=update&' + helper.urlEncode(params),
                tableId: that.config.tableId,
                endCallback: function () {
                    that.reloadTable(null, null)
                }
            });
        },

        // view
        detail: function (obj, config, that) {

            if (!helper.hasKey(config, 'url')) {
                layer.alert('请先配置view请求地址');
                return false
            }

            var condition = helper.getValue(config, 'condition', 'id')
                , params = helper.getCondition(condition, obj.data)
                , label = helper.getValue(config, 'label', '详情')
                , height = helper.getValue(config, 'height', 800);

            func.open({
                height: height,
                title: label,
                content: config.url + '?iframe=1&' + helper.urlEncode(params),
                tableId: that.config.tableId,
                endCallback: function () {
                    // that.reloadTable(null, null)
                }
            });
        },

        // 删除
        delete: function (obj, config, that) {

            // 自定义处理函数
            if (helper.hasKey(config, 'func')) {
                func(obj, config, that)
                return;
            }

            if (!helper.hasKey(config, 'url')) {
                layer.alert('请先配置delete请求地址');
                return false
            }

            var condition = helper.getValue(config, 'condition', 'id')
                , params = helper.getCondition(condition, obj.data),
                afterFunc = helper.getValue(config, 'after', null),
                message = helper.getValue(config, 'message', '确定删除该项目？');

            layer.alert(message, function (index) {
                // 提交配置文件、主键集合、layer的index
                var ajax = new $ax(config.url, function (data) {
                    Kong.success("删除成功！")
                    that.reloadTable(null, null)
                    afterFunc && afterFunc(obj, params, that)
                })
                ajax.setMethod("post")
                ajax.setData(params)
                ajax.send()
                layer.close(index)
            });
        },

    };

    /**
     * 重新渲染排序
     */
    Class.prototype.reloadSort = function () {
        var that = this;
        table.on('sort(' + that.config.tableId + ')', function (order) {
            that.reloadTable(order)
        });
    };


    // 核心入口
    GridView.render = function (options, events) {
        var instance = new Class(options, events);
        return theTable.call(instance);
    };

    exports('gridTree', GridView)
})
